package com.example.kotlinstudy.activity.KTBase.stage2

import com.example.kotlinstudy.bean.Person
import com.example.kotlinstudy.bean.PersonTest
import kotlin.math.roundToInt

/*
总结：
1、如 capitalize()动态生成的字符串不会自动驻留，因此会创建一个新的字符串对象
    val name:String="Fancy"
    val name5= "fancy".capitalize()
    println(name===name5)运行为false
2、数据安全转化
(1)toInt()只能是字符串后.toInt(),不能直接
"666".toInt()
"666.6".toInt() 崩溃//java.lang.NumberFormatException: For input string: "666.6"
"666.6".toIntOrNull()//返回为null
总结：以后有字符串整形相关的转化，尽量用toIntOrNull函数
(2)四舍五入
 println(666.6.roundToInt())
 结论：用roundToInt（）函数，保证 Double ->转Int 持有四含五入的效果
(3)保留4位小数点
"%.4f".format(65.834555)//‘65.8346’
3、空合并操作符 ?:

* */
class KTSecurity {
    /**
     * ?:  必须jinbu
    ======================********六、Kotlin安全调用操作符*********=======================
     */
    companion object {
        const val FANCY = "fancy"
        const val PWD = "1234"
        fun main() {
            //1.？的调用
            var name: String? = "fancy"//声明name的时候name可以为空的情况
//            name = "fancycy"
            val capitalize = name?.capitalize()//为空就返回null，不继续执行
            println("结果是：$capitalize")
        }

        //2、kotlin中使用内置函数，实现空安全的调用
        fun mainLet() {
            var name: String? = null
            name = ""
            val namelet = name?.let {//只有name不为null才执行let里面的函数
                if (it.isBlank()) { //name 是”“ 空值
                    "default"
                } else {
                    "[$it]"
                }

            }
            println(namelet)
        }

        //3、非空断言操作符  !! 可能空指针崩溃 （如果name能保证100%有值，那么才能使用断言，否者有空指针的风险）
        fun security() {//!! 可能空指针崩溃,暴力补救
            var name: String? = null
            val nameSecurity = name!!.capitalize() //和jave一样，不管name是否为null都执行代码
            println("结果是：$nameSecurity")//NullPointerException

            if (name != null) {
                val nameSecurity1 = name.capitalize()
            }
        }

        //4、if 判断是否为空的补救措施
        fun security1() {//!! 可能空指针崩溃,暴力补救
            var name: String? = null
            if (name != null) {
                val nameSecurity1 = name.capitalize()
            }
        }


        //5、自定义的异常
        fun showException() {
            try {
                var info: String? = null
                var isShow: Boolean = false
//                checkException(info)
                checkNotNull(info)//java.lang.IllegalStateException: Required value was null. 就不再执行下方的代码了
//                requireNotNull(info)
                require(isShow)//抛出异常
                println(info!!.length)//NullPointerException

            } catch (e: Exception) {
                println(e)//NullPointerException

            }
        }

        fun checkException(info: String?) {
            info ?: throw CustomException()

        }

        class CustomException : IllegalStateException("你的代码不严谨")

        //6、空合并操作符号
        fun mainLetNUll() {
            var info: String? = "李小龙"
            info = null
            println(info ?: "值为空了")
            info?.let { "[$it]" }
            println(info?.let { "[$it]" } ?: "值为空了")
        }

        //7、substring
        fun mainSub() {
            val name = "fancy is"
            println(name.substring(0, name.indexOf("i")) + "====")
            println(name.substring(0 until name.indexOf('i')) + "===")//这种方式很常见

        }

        //8、Split+结构
        fun mainSplit() {
            val str = "fancy,cathy,lucy,nancy"
            val list = str.split(',')
            println(list)
            //解构到参数中
            val (v1, v2, v3, v4) = list
            println("v1:$v1,v2:$v2")


        }

        //9. replace 完成加密解密操作
        fun mainReplace() {
            val socurcePwd = "ABCDEFJHIJKLMNOPQIS"
            println("原始密码:$socurcePwd")
            val newPwd = socurcePwd.replace(Regex("[ABCD]")) {
                when (it.value) {
                    "A" -> "1"
                    "B" -> "2"
                    "C" -> "3"
                    else -> it.value
                }
            }
            println("新密码:$newPwd")


            val socurcePwdNew = newPwd.replace(Regex("[1234]")) {
                when (it.value) {
                    "1" -> "A"
                    "2" -> "B"
                    "3" -> "C"
                    else -> it.value
                }
            }
            println("解密后的新密码:$socurcePwdNew")
        }

        val name5 = "fancy".capitalize()

        //10.=== 和==的区别   ==是值的比较相当于java中的equals
        fun equal() {
            val name: String = "Fancy"
            val name1: String = "fancy"
            val name2: String = "fancy"
            println(name1.equals(name2))//true
            println(name1 == name2)//true
            println(name1 === name2)//true

            val name4 = name1.capitalize()

            /*
            * 在你的代码中，p1 == p2 会调用 Person 类的 equals() 方法。如果 Person 类没有覆盖 equals() 方法，默认行为是比较对象的内存地址，因此 p1 和 p2 会被认为是不同的对象，即使它们的属性（名字和年龄）是相同的。*/
            println(name1 == name5)//false
            println(name1 === name5)//false

            val p1 = Person("fanxixi", 20)
            val p2 = Person("fanxixi", 20)

            println(p1 == p2)//false
            println(p1 === p2)//false

            val p3 = PersonTest("fanxixi")//true PersonTest自动会equals方法，所以是true
            val p4 = PersonTest("fanxixi")//false

            println(p3 == p4)//true
            println(p3 === p4)//false'

            val p5 = p3
            println(p5 == p3)//true
            println(p3 === p5)//true
            println(name === name5)// false Fancy 在Kotlin（和Java）中，字符串常量（如 "Fancy"）会被驻留（interned），即相同值的字符串常量会共享同一个内存地址。但是，通过方法（如 capitalize()）动态生成的字符串不会自动驻留，因此会创建一个新的字符串对象。

        }


        fun forEach() {
            val str = "ADJKHSJKD";
            str.forEach {
                println("所有的字符串：$it")
            }

            str.forEach {c->
                println("所有的字符串：$c")
            }
        }


       /*数据安全转化*/
        fun numbertransform() {
          val number:Int="666".toInt()

          // val number1:Int="666.6".toInt()//java.lang.NumberFormatException: For input string: "666.6"
           val number2:Int?="666.6".toIntOrNull()//null

           val number3:Double?="666.6".toDoubleOrNull()//666.6
           println(number3 ?: "原来你是null")

           //2、Double 转化为Int
           println(666.6.toInt())//四舍五入
           println(666.6.roundToInt())//四舍五入

           //保留几位小数点
           val r="%.4f".format(65.834555)
           println(r)//四舍五入  65.835
        }

    }

}






